package com.service.admin.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.service.admin.admin.service.SysConfigService;
import com.service.admin.base.service.CoinsPriceService;
import com.service.admin.member.controller.rep.MemberIncomeRep;
import com.service.admin.member.controller.rep.MemberPgeRep;
import com.service.admin.member.controller.rep.MemberRep;
import com.service.admin.member.controller.rep.MemberWalletRep;
import com.service.admin.member.controller.req.*;
import com.service.admin.member.dto.MemberStoreChange;
import com.service.admin.member.enums.MemberEnums;
import com.service.admin.member.service.MemberOutService;
import com.service.admin.member.service.MemberService;
import com.service.admin.member.service.MemberStoreService;
import com.service.admin.order.service.OrderProductHrComboService;
import com.service.admin.support.MemberCacheUtils;
import com.service.admin.support.MemberStoreLockUtils;
import com.service.admin.team.controller.rep.TeamPageRep;
import com.service.admin.team.controller.req.IssuedTeamRewardReq;
import com.service.admin.team.controller.req.TeamPageReq;
import com.service.admin.utils.PwdUtils;
import com.service.core.exception.CommonException;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.*;
import com.service.dao.mapper.*;
import com.service.dao.model.*;
import com.service.dao.po.MemberCache;
import com.service.dao.po.MemberStorePO;
import com.service.utility.common.RandomUtil;
import com.service.utility.modelmapper.ModelMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年09月22日</dd>
 * </dl>
 *
 * @author
 */
@SuppressWarnings("ALL")
@Slf4j
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    @Autowired
    private MemberStoreLockUtils memberStoreLockUtils;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private MemberStoreMapper storeMapper;
    @Autowired
    private MemberWalletMapper memberWalletMapper;
    @Autowired
    private JournalAccountMapper journalAccountMapper;
    @Autowired
    private OrderProductHrComboService orderProductHrComboService;
    @Autowired
    private OrderProductHrComboMapper orderProductHrComboMapper;
    @Autowired
    private MemberCacheUtils memberCacheUtils;
    @Autowired
    private MemberStarGradeConfigMapper memberStarGradeConfigMapper;
    @Autowired
    private CoinsPriceService coinsPriceService;
    @Autowired
    private MemberOutService memberOutService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private MemberStoreService storeService;

    private Integer ModifyMemberGradeBaseNum = 10;

    private Integer ModifyMemberStarGradeBaseNum = 100;


    @Override
    public CommonPageRep<MemberPgeRep> pageMember(MemberPageReq userReq) {
        Page<Member> page = PageHelper.startPage(userReq.getPageNo(), userReq.getPageSize());
        memberMapper.selectByAccount(userReq.getMemberAccount(), userReq.getMemberStatus().getCode());
        List<MemberPgeRep> resultList = page.getResult().stream()
                .map(x -> ModelMapperUtil.getStrictModelMapper().map(x, MemberPgeRep.class)).collect(Collectors.toList());
        return CommonPageRep.buildResultRep(page, resultList);
    }

    @Override
    public void issuedTeamReward(IssuedTeamRewardReq req) {
        Member member = memberMapper.selectById(req.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("用户信息未找到");
        }

        //团队总业绩
        BigDecimal teamPowers = BigDecimal.ZERO;
        //团队总人数
        Integer teamMembers = 0;
        BigDecimal totalMyEffectPowerNums = orderProductHrComboMapper.totalEffectiveOrderByMemberId(req.getMemberId(), req.getCoinsId(), OrderProductOtherStatus.DELIVERED.getCode());
        if (totalMyEffectPowerNums.compareTo(BigDecimal.ZERO) > 0) {
            teamPowers = teamPowers.add(totalMyEffectPowerNums);
            teamMembers = teamMembers + 1;
        } else {
            log.info("当前用户{}没有有效订单", req.getMemberId());
            teamMembers = teamMembers + 1;
        }
        //获取当前用户有效直邀人ID列表
        List<Integer> invitationIds = memberMapper.listValidMemberByPath(req.getMemberId(), GradeEnum.one.getValue());
        if (!ObjectUtils.isEmpty(invitationIds)) {
            //求该用户列表所包含的订单购买USDT之和
            List<OrderProductHrCombo> orderCombos = orderProductHrComboMapper.listEffectiveOrderByMemberIds(invitationIds, CoinsEnum.FIL.getCode(), OrderProductOtherStatus.DELIVERED.getCode());
            if (ObjectUtils.isEmpty(orderCombos)) {
                return;
            } else {
                //计算团队总算力
                BigDecimal teamTotalHashRateNum = orderCombos.stream().map(item -> item.getTotalHashRate()).reduce(BigDecimal.ZERO, BigDecimal::add);
                //读取
                SysConfig sysTeamComConfig = sysConfigService.getByName(ConfigConstants.FIL_TEAM_BUSINESS_MEETS_STANDARDS_COM_NUM);
                SysConfig sysTeamProxyConfig = sysConfigService.getByName(ConfigConstants.FIL_TEAM_BUSINESS_MEETS_STANDARDS_PROXY_NUM);
                BigDecimal teamTotalPayNum = orderCombos.stream().map(item -> item.getOrderMoney()).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal reward = BigDecimal.ZERO;
                boolean isLock = memberStoreLockUtils.lock(member.getId(), CoinsEnum.USDT.getCode());
                if (!isLock) {
                    return;
                }
                if (teamTotalHashRateNum.compareTo(new BigDecimal(sysTeamComConfig.getConfValue())) >= 0) {
                    //达到分公司业绩考核标准
                    SysConfig sysComShareConfig = sysConfigService.getByName(ConfigConstants.TEAM_FIL_COM_REWARD_SCALE);
                    //分红团队订单总花费USDT
                    reward = teamTotalPayNum.multiply(new BigDecimal(sysComShareConfig.getConfValue()));
                    share(member, MemberJAType.FIL_TEAM_BUSINESS_MEETS_STANDARDS_COM_NUM, reward);
                } else if (teamTotalHashRateNum.compareTo(new BigDecimal(sysTeamComConfig.getConfValue())) < 0
                        && teamTotalHashRateNum.compareTo(new BigDecimal(sysTeamProxyConfig.getConfValue())) >= 0) {
                    //达到代理业绩考核标准
                    SysConfig sysProxyShareConfig = sysConfigService.getByName(ConfigConstants.TEAM_FIL_PROXY_REWARD_SCALE);
                    //分红团队订单总花费USDT
                    reward = teamTotalPayNum.multiply(new BigDecimal(sysProxyShareConfig.getConfValue()));
                    share(member, MemberJAType.FIL_TEAM_BUSINESS_MEETS_STANDARDS_PROXY_NUM, reward);
                }
            }
        }
    }

    /**
     * 添加用户团队业绩分红记录
     *
     * @param member
     * @param shareType
     * @param reward
     */
    public void share(Member member, MemberJAType shareType, BigDecimal reward) {
        Date currentDate = new Date();
        String pattern = "yyyy-MM-dd";
        String currentDateStr = DateFormatUtils.format(currentDate, pattern);
        storeService.changeMemberStore(
                MemberStoreChange.builder()
                        .memberId(member.getId())
                        .coinsId(CoinsEnum.USDT.getCode())
                        .coinsName(CoinsEnum.USDT.getName())
                        .jaType(shareType)
                        .changeNum(reward)
                        .remark(currentDateStr + shareType.getMsg().toString())
                        .build());
        memberStoreLockUtils.unlock(member.getId(), CoinsEnum.USDT.getCode());
        log.info("用户<memberId:{},已发放{}所得<{}>", member.getId(), shareType.getMsg().toString(), reward);
    }
    /**
     * 分页查询用户团队
     * 后台设置的相同身份直接截断团队统计
     * @param req
     * @return
     */
//    @Override
//    public CommonPageRep<TeamPageRep> pageMemberTeam(TeamPageReq req) {
//        Page<Member> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
//        memberMapper.selectByAccount(req.getUserAccount(), req.getMemberStatus().getCode());
//        List<TeamPageRep> resultList = page.getResult().stream()
//                .map(x -> ModelMapperUtil.getStrictModelMapper().map(x, TeamPageRep.class)).collect(Collectors.toList());
//        for(TeamPageRep item: resultList){
//            //直推总业绩
//            BigDecimal totalDirectInvitationPowerNums = BigDecimal.ZERO;
//            //直推总人数
//            int totalDirectInviteMember = 0;
//            //间推总业绩
//            BigDecimal totalIndirectInvitePowerNums = BigDecimal.ZERO;
//            //间推总人数
//            int totalIndirectInviteMembers = 0;
//            //团队总业绩
//            BigDecimal teamPowers = BigDecimal.ZERO;
//             //团队总人数
//            Integer teamMembers = 0;
//            //当前根目录节点用户的会员等级  如果团队中有和当前用户等级相同的直接阶段 不纳入统计范围内
//            Integer vipGrade = item.getVipGrade();
//            //统计当前用户的有效算力
//            BigDecimal totalMyEffectPowerNums = orderProductHrComboMapper.totalEffectiveOrderByMemberId(item.getId(), req.getCoinsId(), OrderProductOtherStatus.DELIVERED.getCode());
//            if(totalMyEffectPowerNums.compareTo(BigDecimal.ZERO) <= 0){
//                item.setTotalDirectInviteMember(totalDirectInviteMember);
//                item.setTotalDirectInviteNum(totalDirectInvitationPowerNums);
//                item.setTotalIndirectInviteMember(totalIndirectInviteMembers);
//                item.setTotalIndirectInviteNum(totalIndirectInvitePowerNums);
//                item.setTotalTeamMembers(totalDirectInviteMember+totalIndirectInviteMembers);
//                item.setTotalTeamPerformance(teamPowers);
//                //获取缓存用户信息
//                MemberCache memberCache = memberCacheUtils.getMemberCache(item.getId());
//                if(!ObjectUtils.isEmpty(memberCache)){
//                    memberCache.setFilTeamReleaseNum(teamPowers);
//                    memberCacheUtils.setMemberCache(memberCache);
//                }
//                log.info("当前用户{}没有有效订单",item.getId());
//                continue;
//            }
//            //获取当前用户有效直邀人ID列表
//            List<Integer> directInvitationIds = memberMapper.listMemberDirectInvitationIdsByParam(item.getId(),MemberEnums.Status.ACTIVE.getCode());
//            if(!ObjectUtils.isEmpty(directInvitationIds)){
//                for(Integer directInvitationMemberId:directInvitationIds){
//                    //判断当前用户的vip等级是否
//                    //当前直推用户业绩查询
//                    BigDecimal totalEffectPowerNums = orderProductHrComboMapper.totalEffectiveOrderByMemberId(directInvitationMemberId, req.getCoinsId(), OrderProductOtherStatus.DELIVERED.getCode());
//                    if(totalEffectPowerNums.compareTo(BigDecimal.ZERO) > 0){
//                        totalDirectInvitationPowerNums = totalDirectInvitationPowerNums.add(totalEffectPowerNums);//每个直推用户的业绩添加到直推总业绩中
//                        teamPowers = teamPowers.add(totalEffectPowerNums);
//                    }
//                    totalDirectInviteMember = totalDirectInviteMember + 1;//有效直推人数加1
//                }
//            }
//            //通过直邀用户的id获取间邀用户id列表
//            List<Integer> indirectInviteIds = memberMapper.listMemberIndirectInvitationIdsByParam(item.getId(),MemberEnums.Status.ACTIVE.getCode());
//            if(!ObjectUtils.isEmpty(indirectInviteIds)){
//                for(Integer indirectInviteId: indirectInviteIds){
//                    //间推用户的有效算力
//                    BigDecimal totalindirectInviteEffectPowerNums = orderProductHrComboMapper.totalEffectiveOrderByMemberId(indirectInviteId, req.getCoinsId(), OrderProductOtherStatus.DELIVERED.getCode());
//                    if(totalindirectInviteEffectPowerNums.compareTo(BigDecimal.ZERO) > 0){
//                        totalIndirectInvitePowerNums = totalIndirectInvitePowerNums.add(totalindirectInviteEffectPowerNums);//每个间推推用户的业绩添加到间推推总业绩中
//                        teamPowers = teamPowers.add(totalindirectInviteEffectPowerNums);
//                    }
//                    totalIndirectInviteMembers = totalIndirectInviteMembers + 1;//有效间推推人数加1
//                }
//            }
//            item.setTotalDirectInviteMember(totalDirectInviteMember);
//            item.setTotalDirectInviteNum(totalDirectInvitationPowerNums);
//            item.setTotalIndirectInviteMember(totalIndirectInviteMembers);
//            item.setTotalIndirectInviteNum(totalIndirectInvitePowerNums);
//            item.setTotalTeamMembers(totalDirectInviteMember+totalIndirectInviteMembers);
//            item.setTotalTeamPerformance(teamPowers);
//            //获取缓存用户信息
//            MemberCache memberCache = memberCacheUtils.getMemberCache(item.getId());
//            if(!ObjectUtils.isEmpty(memberCache)){
//                memberCache.setFilTeamReleaseNum(teamPowers);
//                memberCacheUtils.setMemberCache(memberCache);
//            }
//        };
//        return CommonPageRep.buildResultRep(page, resultList);
//    }

    /**
     * 分页查询用户团队
     *
     * @param req
     * @return
     */
    @Override
    public CommonPageRep<TeamPageRep> pageMemberTeamByParam(TeamPageReq req) {
        Page<Member> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        memberMapper.selectByAccount(req.getUserAccount(), req.getMemberStatus().getCode());
        List<TeamPageRep> resultList = page.getResult().stream()
                .map(x -> ModelMapperUtil.getStrictModelMapper().map(x, TeamPageRep.class)).collect(Collectors.toList());
        for (TeamPageRep item : resultList) {
            Integer topVipGrade = item.getVipGrade();
            //查询当前用户下面的有效推荐用户列表
            List<Member> inviteMembers = memberMapper.listEffectInviteMemberByPath(item.getId(), GradeEnum.two.getValue());
            item.setTotalTeamMembers(inviteMembers.size());
            if (ObjectUtils.isEmpty(inviteMembers)) {
                item.setTotalTeamPerformance(BigDecimal.ZERO);
                item.setTotalProxyMembers(0);
                item.setTotalProxyPerformance(BigDecimal.ZERO);
                continue;
            } else {
                List<Integer> inviteMemberIds = inviteMembers.stream().map(Member::getId).collect(Collectors.toList());
                for (Member member : inviteMembers) {
                    //判断当前推荐用户的等级
                    if (topVipGrade >= GradeEnum.three.getValue() && topVipGrade >= GradeEnum.eleven.getValue() || topVipGrade >= GradeEnum.thirteen.getValue()) {
                        //如果顶级用户是分公司 提取出推荐用户中的代理商团对业绩
                        if (topVipGrade == GradeEnum.four.getValue() || topVipGrade == GradeEnum.fourteen.getValue()) {
                            if (member.getVipGrade() == GradeEnum.three.getValue() || member.getVipGrade() == GradeEnum.thirteen.getValue()) {
                                //统计该代理商下面的业绩
                                List<Member> proxyMembers = memberMapper.listEffectInviteMemberByPath(member.getId(), GradeEnum.two.getValue());
                                List<Integer> memberIds = proxyMembers.stream().map(Member::getId).collect(Collectors.toList());
                                BigDecimal totalProxyPerformance = orderProductHrComboService.totalEffectiveOrderByMemberListAndTime(memberIds, req.getStartTime(), req.getEndTime());
                                item.setTotalProxyMembers((item.getTotalProxyMembers() == null ? 0 : item.getTotalProxyMembers()) + 1);
                                item.setTotalProxyPerformance(totalProxyPerformance);
                            }
                        }
                        //确定顶级用户等级是代理或者分公司级别 推荐用户有该等级的直接阶段当前用户下面的团队业绩
                        if (ObjectUtils.nullSafeEquals(item.getVipGrade(), member.getVipGrade()) || ObjectUtils.nullSafeEquals(item.getVipGrade(), member.getVipGrade() + 10)) {
                            //当前用户的团队以下直截断团队收益
                            List<Member> removeMembers = memberMapper.listEffectInviteMemberByPath(member.getId(), GradeEnum.two.getValue());
                            List<Integer> removeIds = removeMembers.stream().map(Member::getId).collect(Collectors.toList());
                            if (!ObjectUtils.isEmpty(removeIds)) {
                                inviteMemberIds.removeAll(removeIds);
                                break;
                            }
                        }
                    } else {
                        item.setTotalProxyMembers(0);
                        item.setTotalProxyPerformance(BigDecimal.ZERO);
                    }
                }
                //统计顶级用户的团队业绩
                if (!ObjectUtils.isEmpty(inviteMemberIds)) {
                    BigDecimal totalTeamPay = orderProductHrComboService.totalEffectiveOrderByMemberListAndTime(inviteMemberIds, req.getStartTime(), req.getEndTime());
                    item.setTotalTeamPerformance(totalTeamPay);
                } else {
                    item.setTotalTeamPerformance(BigDecimal.ZERO);
                    item.setTotalProxyMembers(0);
                    item.setTotalProxyPerformance(BigDecimal.ZERO);
                }
            }
        }
        return CommonPageRep.buildResultRep(page, resultList);
    }

    @Override
    public List<MemberPgeRep> listMember(MemberPageReq userReq) {
        List<Member> memberList = memberMapper.selectByAccount(userReq.getMemberAccount(), userReq.getMemberStatus().getCode());
        return memberList.stream().map(x -> ModelMapperUtil.getStrictModelMapper().map(x, MemberPgeRep.class)).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMember(List<Integer> memberId) {
        for (Integer id : memberId) {
            Member member = memberMapper.selectById(id);
            if (ObjectUtils.isEmpty(member)) {
                throw new CommonException("操作失败，不存在会员id为" + id);
            }
            String userAccount = member.getUserAccount();
            member = new Member();
            member.setId(id);
            member.setUserAccount(userAccount + "-DEL");//已删除
            member.setUserStatus(MemberEnums.Status.DELETE.getCode());
            memberMapper.updateById(member);

            try {
                memberCacheUtils.removeMemberCache(id);//删除redis缓存
            } catch (Exception e) {
                log.info("没有该会员的缓存信息");
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void lockMember(List<Integer> memberId) {
        for (Integer id : memberId) {
            Member member = memberMapper.selectById(id);
            if (ObjectUtils.isEmpty(member)) {
                throw new CommonException("操作失败，不存在会员id为" + id);
            }
            member = new Member();
            member.setId(id);
            member.setUserStatus(MemberEnums.Status.LOCK.getCode());
            memberMapper.updateById(member);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void invalidMember(List<Integer> memberId) {
        for (Integer id : memberId) {
            Member member = memberMapper.selectById(id);
            if (ObjectUtils.isEmpty(member)) {
                throw new CommonException("操作失败，不存在会员id为" + id);
            }
            member = new Member();
            member.setId(id);
            member.setUserStatus(MemberEnums.Status.INVALID.getCode());
            memberMapper.updateById(member);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(ResetPwdReq resetPwdReq) {
        Member member = memberMapper.selectById(resetPwdReq.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("操作失败，不存在此会员");
        }
        member = new Member();
        member.setId(resetPwdReq.getMemberId());
        if (resetPwdReq.getType() == 0) {
            member.setLoginSalt(RandomUtil.randomString(4));
            member.setLoginPwd(PwdUtils.aesToMd5(resetPwdReq.getPassword(), member.getLoginSalt()));
        } else {
            member.setSafetySalt(RandomUtil.randomString(4));
            member.setSafetyPwd(PwdUtils.aesToMd5(resetPwdReq.getPassword(), member.getSafetySalt()));
        }
        memberMapper.updateById(member);
    }

    @Override
    public MemberRep detail(Integer memberId) {
        Member member = memberMapper.selectById(memberId);
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("操作失败，不存在此会员");
        }
        List<String> pathAccounts = null;
        if (StringUtils.isNotEmpty(member.getUserPath())) {
            String[] ids = member.getUserPath().split("-");
            List<Integer> idList = new ArrayList<>();
            for (String id : ids) {
                if (StringUtils.isNotEmpty(id)) {
                    idList.add(Integer.parseInt(id));
                }
            }
            if (idList.size() > 0) {
                pathAccounts = memberMapper.selectAccountByIds(idList);
            }
        }
        List<Member> childrens = selectByPid(memberId);

        MemberRep result = ModelMapperUtil.getStrictModelMapper().map(member, MemberRep.class);
        List<MemberWallet> walletList = memberWalletMapper.selectByName(null, memberId, 1);
        Map<String, BigDecimal> coinPriceMap = coinsPriceService.getStandardPrice2Map();
        BigDecimal filStanderPrice = coinPriceMap.get(CoinsEnum.FIL.getName());

        MemberIncomeRep yesterdayIncome = getYesterdayIncome(memberId);
        result.setYesterdayIncome(yesterdayIncome.getAwardIncome().add(yesterdayIncome.getMiningIncome().multiply(filStanderPrice)));

        result.setPathAccounts(pathAccounts);
        result.setChildrens(childrens);
        MemberIncomeRep totalIncome = getMemberAccumulatedIncome(memberId);
        result.setAccumulatedIncome(totalIncome.getAwardIncome().add(totalIncome.getMiningIncome().multiply(filStanderPrice)));

        List<MemberWalletRep> walletReps = walletList.stream().map(x -> ModelMapperUtil.getStrictModelMapper().map(x, MemberWalletRep.class)).collect(Collectors.toList());
        result.setWalletList(walletReps);

        result.setStoreList(listMemberStore(memberId));
        //设置流通账户余额 开始
        List<MemberStore> memberStores = storeService.selectByMemberId(member.getId(), CommonStatusEnums.ACTIVE.getCode());
        memberStores.stream().forEach(memberStore -> {
            if (memberStore.getCoinsId() == CoinsEnum.FIL.getCode()) {
                result.setCurrencyFIL(memberStore.getNum());
            } else if (memberStore.getCoinsId() == CoinsEnum.BTC.getCode()) {
                result.setCurrencyBTC(memberStore.getNum());
            } else if (memberStore.getCoinsId() == CoinsEnum.USDT.getCode()) {
                result.setCurrencyUSDT(memberStore.getNum());
            }
        });
        //设置流通账户余额 结束
        String pattern = "yyyy-MM-dd";
        Date currentDate = new Date();
        String currentDateStr = DateFormatUtils.format(currentDate, pattern);
        result.setTodayRechargeUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.USDT.getName(), MemberJAType.getRechargeType(), currentDateStr));
        result.setTotalRechargeUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.USDT.getName(), MemberJAType.getRechargeType(), null));
        result.setTodayWithdrawUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.USDT.getName(), MemberJAType.getWithdrawType(), currentDateStr));
        result.setTotalWithdrawUSDT(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.USDT.getName(), MemberJAType.getWithdrawType(), null));
        result.setTodayWithdrawFIL(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.FIL.getName(), MemberJAType.getWithdrawType(), currentDateStr));
        result.setTotalWithdrawFIL(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.FIL.getName(), MemberJAType.getWithdrawType(), null));
        result.setTodayReleaseFIL(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.FIL.getName(), MemberJAType.getReleaseType(), currentDateStr));
        result.setTotalReleaseFIL(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.FIL.getName(), MemberJAType.getReleaseType(), null));
        result.setTodayReleaseBTC(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.BTC.getName(), MemberJAType.getReleaseType(), currentDateStr));
        result.setTotalReleaseBTC(journalAccountMapper.getSomedayTotalStatementByCoins(memberId, CoinsEnum.BTC.getName(), MemberJAType.getReleaseType(), null));
        result.setTodayBuyFIL(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(memberId, CoinsEnum.FIL.getName(), currentDateStr));
        result.setTotalBuyFIL(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(memberId, CoinsEnum.FIL.getName(), null));
        result.setTodayBuyBTC(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(memberId, CoinsEnum.BTC.getName(), currentDateStr));
        result.setTotalBuyBTC(orderProductHrComboMapper.totalTodayBuyByMemberIdAndCoinsIdAndSomeDay(memberId, CoinsEnum.BTC.getName(), null));
        return result;
    }

    private List<MemberStorePO> listMemberStore(Integer userId) {
        List<MemberStore> storeList = storeMapper.selectByMemberId(userId, CommonStatusEnums.ACTIVE.getCode());
        if (ObjectUtils.isEmpty(storeList)) {
            return Lists.newArrayList();
        }
        return storeList.stream().map(x -> ModelMapperUtil.getStrictModelMapper().map(x, MemberStorePO.class)).collect(Collectors.toList());
    }

    private MemberIncomeRep getMemberAccumulatedIncome(Integer memberId) {

        MemberOut memberOut = memberOutService.getLastMemberOutRecord(memberId);
        Date outTime = null;
        if (!ObjectUtils.isEmpty(memberOut)) {
            outTime = memberOut.getCreateTime();
        }
        BigDecimal awardIncome = journalAccountMapper.getAccumulatedIncome(memberId, MemberJAType.getAwardIncomeType(), outTime);
        BigDecimal miningIncome = journalAccountMapper.getAccumulatedIncome(memberId, MemberJAType.getMiningIncomeType(), null);

        return MemberIncomeRep.builder()
                .awardIncome(awardIncome)
                .miningIncome(miningIncome)
                .build();
    }

    private MemberIncomeRep getYesterdayIncome(Integer memberId) {
        Date yesterday = DateUtils.addDays(new Date(), -1);
        return MemberIncomeRep.builder()
                .awardIncome(this.getSomedayAwardIncome(memberId, yesterday))
                .miningIncome(this.getSomedayMiningIncome(memberId, yesterday))
                .build();
    }

    /**
     * 获取某一天会员收益
     *
     * @param memberId
     * @return
     */
    private BigDecimal getSomedayAwardIncome(Integer memberId, Date someday) {
        return journalAccountMapper.getSomedayIncome(memberId, MemberJAType.getAwardIncomeType(), DateFormatUtils.format(someday, "yyyy-MM-dd"));
    }

    /**
     * 获取某一天会员收益
     *
     * @param memberId
     * @return
     */
    private BigDecimal getSomedayMiningIncome(Integer memberId, Date someday) {
        return journalAccountMapper.getSomedayIncome(memberId, MemberJAType.getMiningIncomeType(), DateFormatUtils.format(someday, "yyyy-MM-dd"));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMemberGrade(ModifyMemberGradeReq gradeReq) {
        Member member = getById(gradeReq.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("此会员不存在");
        }

        Integer memberGrade = gradeReq.getGrade();
        if (isAddBaseNum(member.getVipGrade(), memberGrade)) {
            memberGrade += 10;
        }

        updateById(Member.builder().id(gradeReq.getMemberId()).vipGrade(memberGrade).build());
        memberCacheUtils.removeMemberCache(gradeReq.getMemberId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMemberStarGrade(ModifyMemberStarGradeReq gradeReq) {
        Member member = getById(gradeReq.getMemberId());
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("此会员不存在");
        }

        Integer memberGrade = gradeReq.getGrade();
        if (isAddStarGradeBaseNum(member.getStarGrade(), memberGrade)) {
            memberGrade += 100;
        }

        updateById(Member.builder().id(gradeReq.getMemberId()).starGrade(memberGrade).build());
        memberCacheUtils.removeMemberCache(gradeReq.getMemberId());
    }

    private boolean isAddBaseNum(Integer vipGrade, Integer target) {
        return vipGrade < ModifyMemberGradeBaseNum ||
                vipGrade > ModifyMemberGradeBaseNum
                        && target > vipGrade - ModifyMemberGradeBaseNum;
    }

    private boolean isAddStarGradeBaseNum(Integer vipGrade, Integer target) {
        return vipGrade < ModifyMemberStarGradeBaseNum ||
                vipGrade > ModifyMemberStarGradeBaseNum
                        && target > vipGrade - ModifyMemberStarGradeBaseNum;
    }

    @Override
    public List<Member> listByAccount(String memberAccount) {
        return memberMapper.selectByAccount(memberAccount, MemberEnums.Status.ACTIVE.getCode());
    }

    @Override
    public Member getMemberByAccount(String userAccount) {
        Member member = this.getOne(new QueryWrapper<Member>().lambda()
                .eq(Member::getUserAccount, userAccount)
                .eq(Member::getUserStatus, CommonStatusEnums.ACTIVE.getCode())
                .eq(Member::getActivate, CommonStatusEnums.ACTIVE.getCode()));
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("不存在此会员");
        }
        return member;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNewCoin2MemberAssert(CoinsEnum coins) {
        List<Member> memberList = list(new LambdaQueryWrapper<Member>()
                .eq(Member::getUserStatus, MemberEnums.Status.ACTIVE.getCode()));

        List<MemberStore> storeList = Lists.newLinkedList();
        Date currentDate = new Date();
        memberList.parallelStream().forEach(item -> {
            MemberStore memberStore = storeService.getMemberStore(item.getId(), coins.getName());
            if (!ObjectUtils.isEmpty(memberStore)) {
                return;
            }

            storeList.add(MemberStore.builder()
                    .memberId(item.getId())
                    .coinsId(coins.getCode())
                    .coinsName(coins.getName())
                    .num(BigDecimal.ZERO)
                    .frostNum(BigDecimal.ZERO)
                    .createTime(currentDate)
                    .build());
        });

        storeService.saveBatch(storeList);
    }

    /**
     * 查询直推有效会员
     *
     * @param memberId
     * @return
     */
    @Override
    public List<Member> selectByPid(Integer memberId) {
        return list(new QueryWrapper<Member>().lambda().eq(Member::getPid, memberId)
                .eq(Member::getUserStatus, CommonStatusEnums.ACTIVE.getCode())
                .eq(Member::getActivate, CommonStatusEnums.ACTIVE.getCode()));
    }

    /**
     * 修改冻结状态
     *
     * @param req
     */
    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public void updateStoreFreezeStatus(UpdateStoreFreezeStatusReq updateStoreFreezeStatusReq) {
        Assert.notNull(updateStoreFreezeStatusReq, "参数 [updateStoreFreezeStatusReq] 不能为 null");
        Assert.notNull(updateStoreFreezeStatusReq.getId(), "参数 [id] 不能为 null");
        Assert.notNull(updateStoreFreezeStatusReq.getStoreFreezeStatus(), "参数 [storeFreezeStatus] 不能为 null");
        Member member = memberMapper.selectOne(new LambdaQueryWrapper<Member>().eq(Member::getId, updateStoreFreezeStatusReq.getId()));
        if (ObjectUtils.isEmpty(member)) {
            throw new CommonException("用户异常");
        }
        member.setStoreFreezeStatus(updateStoreFreezeStatusReq.getStoreFreezeStatus());
        memberMapper.updateById(member);
    }
}
